﻿/*!
* Ext JS Library 3.2.0
* Copyright(c) 2006-2010 Ext JS, Inc.
* licensing@extjs.com
* http://www.extjs.com/license
*/
Ext.ns('Ext.ux.tree');

/**
* @class Ext.ux.tree.XmlTreeLoader
* @extends Ext.tree.TreeLoader
* <p>A TreeLoader that can convert an XML document into a hierarchy of {@link Ext.tree.TreeNode}s.
* Any text value included as a text node in the XML will be added to the parent node as an attribute
* called <tt>innerText</tt>.  Also, the tag name of each XML node will be added to the tree node as
* an attribute called <tt>tagName</tt>.</p>
* <p>By default, this class expects that your source XML will provide the necessary attributes on each
* node as expected by the {@link Ext.tree.TreePanel} to display and load properly.  However, you can
* provide your own custom processing of node attributes by overriding the {@link #processNode} method
* and modifying the attributes as needed before they are used to create the associated TreeNode.</p>
* @constructor
* Creates a new XmlTreeloader.
* @param {Object} config A config object containing config properties.
*/
Ext.ux.tree.XmlTreeLoader = Ext.extend(Ext.tree.TreeLoader, {
    /**
    * @property  XML_NODE_ELEMENT
    * XML element node (value 1, read-only)
    * @type Number
    */
    XML_NODE_ELEMENT: 1,
    /**
    * @property  XML_NODE_TEXT
    * XML text node (value 3, read-only)
    * @type Number
    */
    XML_NODE_TEXT: 3,

    // private override
    processResponse: function(response, node, callback) {
        var xmlData = response.responseXML;
        var root = xmlData.documentElement || xmlData;

        try {
            node.beginUpdate();
            node.appendChild(this.parseXml(root));
            node.endUpdate();

            if (typeof callback == "function") {
                callback(this, node);
            }
        } catch (e) {
            this.handleFailure(response);
        }
    },

    // private
    parseXml: function(node) {
        var nodes = [];
        Ext.each(node.childNodes, function(n) {
            if (n.nodeType == this.XML_NODE_ELEMENT) {
                var treeNode = this.createNode(n);
                if (n.childNodes.length > 0) {
                    var child = this.parseXml(n);
                    if (typeof child == 'string') {
                        treeNode.attributes.innerText = child;
                    } else {
                        treeNode.appendChild(child);
                    }
                }
                nodes.push(treeNode);
            }
            else if (n.nodeType == this.XML_NODE_TEXT) {
                var text = n.nodeValue.trim();
                if (text.length > 0) {
                    return nodes = text;
                }
            }
        }, this);

        return nodes;
    },

    // private override
    createNode: function(node) {
        var attr = {
            tagName: node.tagName
        };

        Ext.each(node.attributes, function(a) {
            attr[a.nodeName] = a.nodeValue;
        });

        this.processAttributes(attr);

        return Ext.ux.tree.XmlTreeLoader.superclass.createNode.call(this, attr);
    },

    /*
    * Template method intended to be overridden by subclasses that need to provide
    * custom attribute processing prior to the creation of each TreeNode.  This method
    * will be passed a config object containing existing TreeNode attribute name/value
    * pairs which can be modified as needed directly (no need to return the object).
    */
    processAttributes: Ext.emptyFn
});

//backwards compat
Ext.ux.XmlTreeLoader = Ext.ux.tree.XmlTreeLoader;


Ext.app.BookLoader = Ext.extend(Ext.ux.tree.XmlTreeLoader, {
    processAttributes: function(attr) {
        if (attr.first) {

            attr.text = attr.first + ' ' + attr.last;

            attr.iconCls = 'author' + attr.gender;

            attr.loaded = true;

            attr.expanded = true;
        }
        else if (attr.title) {

            attr.text = attr.title + '(' + attr.published + ')';

            attr.iconCls = 'book';

            attr.leaf = true;
        }
    }
});

Ext.onReady(function() {
    var detailsTest = '<i>Select a book to see more infomation...</i>';

    var tpl = new Ext.Template(
        '<h2 class="title">{title}<h2>',
        '<p><b>Published</b>:{published}</p>',
        '<p><b>Synopsis</b>:{innerText}</p>',
        '<p><a href="{url}" target="_blank">Purchase from Amazon</a></p>'
    );
    tpl.compile();

    new Ext.Panel({
        title: 'Reading List',
        renderTo: 'tree',
        layout: 'border',
        width: 500,
        height: 500,
        items: [{
            xtype: 'treepanel',
            id: 'tree-panel',
            region: 'center',
            margins: '2 2 0 2',
            autoScroll: true,
            rootVisible: false,
            root: new Ext.tree.AsyncTreeNode(),

            loader: new Ext.app.BookLoader({
            dataUrl: 'http://www.extjs.com/deploy/dev/examples/tree/xml-tree-data.xml',
                requestMethod: 'GET'
            }),

            listeners: {
                'render': function(tp) {
                    tp.getSelectionModel().on('selectionchange', function(tree, node) {
                        var el = Ext.getCmp('details-panel').body;
                        if (node && node.leaf) {
                            tpl.overwrite(el.node.attributes);
                        } else {
                            el.update(detailsTest);
                        }
                    })
                }
            }
        }, {
            region: 'south',
            title: 'Book Details',
            id: 'details-panel',
            autoScroll: true,
            collapsible: true,
            split: true,
            margins: '0 2 2 2',
            cmargins: '2 2 2 2',
            height: 220,
            html: detailsTest
            }]
        });
    });
            